package cn.chinaflame.pagodas.utils;

import cn.chinaflame.pagodas.constant.Sysconst;
import cn.chinaflame.pagodas.enums.CodeEnum;
import cn.chinaflame.pagodas.handle.HandlerException;
import com.google.common.base.Objects;
import com.google.common.base.Strings;
import com.google.gson.Gson;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.regex.Pattern;


/**
 * @author crated by boming 2017年5月27日 下午4:08:13
 */
public class ParamPreconditions {

    private static Logger log = LoggerFactory.getLogger(ParamPreconditions.class);

    /**
     * 字符串为空校验
     *
     * @param str     待校验字符串
     * @param code    错误码
     * @param errMsg  错误信息
     * @param message 异常信息
     */
    public static void checkNotEmpty(String str, String code, String errMsg, String message) {
        if (str == null || (str = str.trim()).length() == 0)
            throw new HandlerException(code, errMsg, message);
    }

    /**
     * 校验字符串数组不能存在空值
     *
     * @param code    错误码
     * @param errMsg  错误信息
     * @param message 异常信息
     * @param str     待校验字符数组
     */
    public static void checkNotEmpty(String code, String errMsg, String message, String... str) {
        for (String content : str) {
            if (content == null || (content = content.trim()).length() == 0)
                throw new HandlerException(code, errMsg, message);
        }
    }

    /**
     * 字符串为空校验
     *
     * @param str
     * @param code
     * @param errMsg
     */
    public static void checkNotEmpty(String str, String code, String errMsg) {
        if (str == null || (str = str.trim()).length() == 0 || Objects.equal(str, "null"))
            throw new HandlerException(code, errMsg, errMsg);
    }

    /**
     * 对象为null校验
     *
     * @param o
     * @param code
     * @param errMsg
     * @param message
     */
    public static void checkNotNull(Object o, String code, String errMsg, String message) {
        if (o == null)
            throw new HandlerException(code, errMsg, message);
    }

    /**
     * 对象为null校验
     *
     * @param o
     * @param code
     * @param errMsg
     */
    public static void checkNotNull(Object o, String code, String errMsg) {
        if (o == null)
            throw new HandlerException(code, errMsg, errMsg);
    }

    /**
     * 校验是否满足表达式要求
     *
     * @param expression
     * @param code
     * @param errMsg
     * @param message
     */
    public static void checkArgument(boolean expression, String code, String errMsg, String message) {
        if (!expression)
            throw new HandlerException(code, errMsg, message);
    }

    /**
     * 校验是否满足表达式要求
     *
     * @param expression 待校验表达式
     * @param code       返回码
     * @param errMsg     返回错误信息
     */
    public static void checkArgument(boolean expression, String code, String errMsg) {
        if (!expression)
            throw new HandlerException(code, errMsg, errMsg);
    }

    /**
     * 检查是否不满足表达式要求
     *
     * @param expression
     * @param code
     * @param errMsg
     * @param message
     */
    public static void checkArgumentNon(boolean expression, String code, String errMsg, String message) {
        if (expression)
            throw new HandlerException(code, errMsg, message);
    }

    /**
     * 检查是否不满足表达式要求
     *
     * @param expression
     * @param code
     * @param errMsg
     */
    public static void checkArgumentNon(boolean expression, String code, String errMsg) {
        if (expression)
            throw new HandlerException(code, errMsg, errMsg);
    }

    /**
     * 检查是否整数型字符串
     *
     * @param intStr
     * @return
     */
    public static boolean checkIntegerFmt(String intStr) {
        log.info("字符串是否为整数intStr:{}", intStr);
        try {
            Integer.parseInt(intStr);
        } catch (Exception e) {
            log.error("非整数型字符串intStr:{}", intStr, e);
            return false;
        }
        return true;
    }

    /**
     * 校验邮箱格式是否正确
     *
     * @param intStr
     * @return
     */
    public static void checkEmailFmt(String email) {
        log.info("校验邮箱格式是否正确email:{}", email);
        if (!Pattern.matches("\\p{Alpha}\\w{2,15}[@][a-z0-9]{3,}[.]\\p{Lower}{2,}", email))
            throw new HandlerException(CodeEnum.FAIL.getCode(), "邮箱格式不正确", "邮箱格式不正确");
    }

    /**
     * 校验手机号格式是否正确
     *
     * @param mobile
     */
    public static void checkMobileFmt(String mobile) {
        log.info("校验手机号格式是否正确mobile:{}", mobile);
//		if(!Pattern.matches("^((13[0-9])|(15[^4,\\D])|(18[0-9]))\\d{8}$", mobile))
//			throw new HandlerException(CodeEnum.FAIL.getCode(), "手机号码格式不正确", "手机号码格式不正确");
    }

    /**
     * 校验手机号格式是否正确
     *
     * @param mobile
     */
    public static void checkMobileFmt(String mobile, String code, String msg, String message) {
        log.info("校验手机号格式是否正确mobile:{}", mobile);
        if (!Pattern.matches("^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$", mobile))
            throw new HandlerException(code, "手机号码格式不正确", "手机号码格式不正确");
    }

    public static void checkDateByFmt(String dateStr, String pattern, String code, String msg) {
        try {
            DateUtils.parseDateStrictly(dateStr, pattern);
        } catch (ParseException e) {
            throw new HandlerException(code, msg, msg, e);
        }
    }

    public static void checkDateByFmt(String dateStr, String pattern) {
        try {
            DateUtils.parseDateStrictly(dateStr, pattern);
        } catch (ParseException e) {
            throw new HandlerException(CodeEnum.FAIL.getCode(), "日期格式不符", "日期格式不符", e);
        }
    }

    public static void checkNumberByDecimals(BigDecimal number, int dcimals) {
        if (number == null || number.compareTo(BigDecimal.ZERO) <= 0 || number.scale() <= dcimals)
            throw new HandlerException(CodeEnum.FAIL.getCode(), "数字格式有误（大于0，且保留两位小数）", "数字格式有误（大于0，且保留两位小数）");
    }
    
    public static void checkNumberByMoney(BigDecimal number) {
        if (number == null || number.compareTo(BigDecimal.ZERO) <= 0 )
            throw new HandlerException(CodeEnum.FAIL.getCode(), "数字格式有误（大于0）", "数字格式有误（大于0）");
    }
    
    

    public static void checkNumberByDecimals(BigDecimal number, int dcimals, String code, String msg) {
        if (number == null || number.compareTo(BigDecimal.ZERO) <= 0 || number.scale() > dcimals)
            throw new HandlerException(code, msg, msg);
    }

    public static void checkSexValid(String sex) {
        checkArgument(Sysconst.SEX_MAN.equals(sex) || Sysconst.SEX_WOMAN.equals(sex),
                CodeEnum.FAIL.getCode(), "性别有误[0-男;1-女]");
    }

    public static void checkPriceValid(BigDecimal price) {
        checkNumberByDecimals(price, 2, CodeEnum.FAIL.getCode(), "价格保留两位小数且大于0");
    }

    public static void checkTransTypeValid(String transType) {
        checkArgument(Sysconst.TransTypeList.contains(transType), CodeEnum.FAIL.getCode(), "错误的交易类型");
    }

    public static void checkPayTypeValid(String payType) {
//		checkArgument(Sysconst.IDTYPE_PASSPORT.contains(transType), CodeEnum.FAIL.getCode(), "错误的交易类型");
    }

    public static void checkBirthdayValid(String birth) {
        checkDateByFmt(birth, DateTimes.DATE_PATTERN2, CodeEnum.FAIL.getCode(), "出生日期格式不正确【yyyy-MM-dd】");
    }

    public static void checkParamsNotEmpty(String... str) {
        checkNotEmpty(CodeEnum.FAIL.getCode(), "必要参数为空", "必要参数为空", str);
    }

    public static void checkChannelValid(String channel) {
        checkArgument(Sysconst.OrderChannelList.contains(channel), CodeEnum.FAIL.getCode(), "错误的渠道代码");
    }

    public static void checkOrderTypeValid(String orderType) {
        checkArgument(Sysconst.OrderTypeList.contains(orderType), CodeEnum.FAIL.getCode(), "错误的订单类型");
    }

    public static void checkMemberPrimiaryValid(String memberId, String mobile, String openid, String email) {
        checkArgument(!Strings.isNullOrEmpty(openid) ||
                !Strings.isNullOrEmpty(memberId) || !Strings.isNullOrEmpty(mobile) || !Strings.isNullOrEmpty(email), CodeEnum.FAIL.getCode(), "会员唯一标识不能为空");
    }

    public static String toJson(Object object) {
        Gson gson = new Gson();
        return gson.toJson(object);
    }

    public static <E> E fromJson(String jsonObj, Class<E> c) {
        Gson gson = new Gson();
        return gson.fromJson(jsonObj, c);
    }

}
